{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0b9a3d83",
   "metadata": {},
   "source": [
    "# Lesson 6: Planning and Stock Report Generation"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8d5f1491",
   "metadata": {},
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ad72cb6c-a916-40f7-960c-501c6309037f",
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "llm_config={\"model\": \"gpt-4-turbo\"}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d09b03c3",
   "metadata": {},
   "source": [
    "## The task!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "01c1772f-2583-4c7a-a8a0-dd2946eea022",
   "metadata": {
    "height": 63
   },
   "outputs": [],
   "source": [
    "task = \"Write a blogpost about the stock price performance of \"\\\n",
    "\"Nvidia in the past month. Today's date is 2024-04-23.\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be3ca91b",
   "metadata": {},
   "source": [
    "## Build a group chat\n",
    "\n",
    "This group chat will include these agents:\n",
    "\n",
    "1. **User_proxy** or **Admin**: to allow the user to comment on the report and ask the writer to refine it.\n",
    "2. **Planner**: to determine relevant information needed to complete the task.\n",
    "3. **Engineer**: to write code using the defined plan by the planner.\n",
    "4. **Executor**: to execute the code written by the engineer.\n",
    "5. **Writer**: to write the report."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bd7befab-9487-4c50-8eca-1e2e30dbf7d6",
   "metadata": {
    "height": 29
   },
   "outputs": [],
   "source": [
    "import autogen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3258cb72-cb74-4eab-a387-ee409baf4947",
   "metadata": {
    "height": 148
   },
   "outputs": [],
   "source": [
    "user_proxy = autogen.ConversableAgent(\n",
    "    name=\"Admin\",\n",
    "    system_message=\"Give the task, and send \"\n",
    "    \"instructions to writer to refine the blog post.\",\n",
    "    code_execution_config=False,\n",
    "    llm_config=llm_config,\n",
    "    human_input_mode=\"ALWAYS\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0832b856-f13d-4e16-b61f-69eb23e0ae71",
   "metadata": {
    "height": 301
   },
   "outputs": [],
   "source": [
    "planner = autogen.ConversableAgent(\n",
    "    name=\"Planner\",\n",
    "    system_message=\"Given a task, please determine \"\n",
    "    \"what information is needed to complete the task. \"\n",
    "    \"Please note that the information will all be retrieved using\"\n",
    "    \" Python code. Please only suggest information that can be \"\n",
    "    \"retrieved using Python code. \"\n",
    "    \"After each step is done by others, check the progress and \"\n",
    "    \"instruct the remaining steps. If a step fails, try to \"\n",
    "    \"workaround\",\n",
    "    description=\"Planner. Given a task, determine what \"\n",
    "    \"information is needed to complete the task. \"\n",
    "    \"After each step is done by others, check the progress and \"\n",
    "    \"instruct the remaining steps\",\n",
    "    llm_config=llm_config,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2427f55d-fb7b-4f3c-85d4-dcd35547b397",
   "metadata": {
    "height": 131
   },
   "outputs": [],
   "source": [
    "engineer = autogen.AssistantAgent(\n",
    "    name=\"Engineer\",\n",
    "    llm_config=llm_config,\n",
    "    description=\"An engineer that writes code based on the plan \"\n",
    "    \"provided by the planner.\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "429ed9f1",
   "metadata": {},
   "source": [
    "**Note**: In this lesson, you'll use an alternative method of code execution by providing a dict config. However, you can always use the LocalCommandLineCodeExecutor if you prefer. For more details about code_execution_config, check this: https://microsoft.github.io/autogen/docs/reference/agentchat/conversable_agent/#__init__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "040ac21f-b4bf-4bd6-ac58-fdb2c8f8de14",
   "metadata": {
    "height": 199
   },
   "outputs": [],
   "source": [
    "executor = autogen.ConversableAgent(\n",
    "    name=\"Executor\",\n",
    "    system_message=\"Execute the code written by the \"\n",
    "    \"engineer and report the result.\",\n",
    "    human_input_mode=\"NEVER\",\n",
    "    code_execution_config={\n",
    "        \"last_n_messages\": 3,\n",
    "        \"work_dir\": \"coding\",\n",
    "        \"use_docker\": False,\n",
    "    },\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d6367fb4-a81b-411c-a339-8dd3d1d41483",
   "metadata": {
    "height": 216
   },
   "outputs": [],
   "source": [
    "writer = autogen.ConversableAgent(\n",
    "    name=\"Writer\",\n",
    "    llm_config=llm_config,\n",
    "    system_message=\"Writer.\"\n",
    "    \"Please write blogs in markdown format (with relevant titles)\"\n",
    "    \" and put the content in pseudo ```md``` code block. \"\n",
    "    \"You take feedback from the admin and refine your blog.\",\n",
    "    description=\"Writer.\"\n",
    "    \"Write blogs based on the code execution results and take \"\n",
    "    \"feedback from the admin to refine the blog.\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2ea86b5",
   "metadata": {},
   "source": [
    "## Define the group chat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cbf3c4b7-d4b8-4f97-8a25-e23107904ad5",
   "metadata": {
    "height": 97
   },
   "outputs": [],
   "source": [
    "groupchat = autogen.GroupChat(\n",
    "    agents=[user_proxy, engineer, writer, executor, planner],\n",
    "    messages=[],\n",
    "    max_round=10,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bfcabc20-9316-45b7-852d-42e14550a956",
   "metadata": {
    "height": 80
   },
   "outputs": [],
   "source": [
    "manager = autogen.GroupChatManager(\n",
    "    groupchat=groupchat, llm_config=llm_config\n",
    ")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b51eaffa",
   "metadata": {},
   "source": [
    "## Start the group chat!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5dd69615",
   "metadata": {},
   "source": [
    "<p style=\"background-color:#ECECEC; padding:15px; \"> <b>Note:</b> In this lesson, you will use GPT 4 for better results. Please note that the lesson has a quota limit. If you want to explore the code in this lesson further, we recommend trying it locally with your own API key."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a9899e8f-2971-487c-9d0e-932c36b3b75a",
   "metadata": {
    "height": 80
   },
   "outputs": [],
   "source": [
    "groupchat_result = user_proxy.initiate_chat(\n",
    "    manager,\n",
    "    message=task,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba5d14b6",
   "metadata": {},
   "source": [
    "## Add a speaker selection policy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c17e5a76-3c40-4e2a-b8f1-378f901f5b74",
   "metadata": {
    "height": 981
   },
   "outputs": [],
   "source": [
    "user_proxy = autogen.ConversableAgent(\n",
    "    name=\"Admin\",\n",
    "    system_message=\"Give the task, and send \"\n",
    "    \"instructions to writer to refine the blog post.\",\n",
    "    code_execution_config=False,\n",
    "    llm_config=llm_config,\n",
    "    human_input_mode=\"ALWAYS\",\n",
    ")\n",
    "\n",
    "planner = autogen.ConversableAgent(\n",
    "    name=\"Planner\",\n",
    "    system_message=\"Given a task, please determine \"\n",
    "    \"what information is needed to complete the task. \"\n",
    "    \"Please note that the information will all be retrieved using\"\n",
    "    \" Python code. Please only suggest information that can be \"\n",
    "    \"retrieved using Python code. \"\n",
    "    \"After each step is done by others, check the progress and \"\n",
    "    \"instruct the remaining steps. If a step fails, try to \"\n",
    "    \"workaround\",\n",
    "    description=\"Given a task, determine what \"\n",
    "    \"information is needed to complete the task. \"\n",
    "    \"After each step is done by others, check the progress and \"\n",
    "    \"instruct the remaining steps\",\n",
    "    llm_config=llm_config,\n",
    ")\n",
    "\n",
    "engineer = autogen.AssistantAgent(\n",
    "    name=\"Engineer\",\n",
    "    llm_config=llm_config,\n",
    "    description=\"Write code based on the plan \"\n",
    "    \"provided by the planner.\",\n",
    ")\n",
    "\n",
    "writer = autogen.ConversableAgent(\n",
    "    name=\"Writer\",\n",
    "    llm_config=llm_config,\n",
    "    system_message=\"Writer. \"\n",
    "    \"Please write blogs in markdown format (with relevant titles)\"\n",
    "    \" and put the content in pseudo ```md``` code block. \"\n",
    "    \"You take feedback from the admin and refine your blog.\",\n",
    "    description=\"After all the info is available, \"\n",
    "    \"write blogs based on the code execution results and take \"\n",
    "    \"feedback from the admin to refine the blog. \",\n",
    ")\n",
    "\n",
    "executor = autogen.ConversableAgent(\n",
    "    name=\"Executor\",\n",
    "    description=\"Execute the code written by the \"\n",
    "    \"engineer and report the result.\",\n",
    "    human_input_mode=\"NEVER\",\n",
    "    code_execution_config={\n",
    "        \"last_n_messages\": 3,\n",
    "        \"work_dir\": \"coding\",\n",
    "        \"use_docker\": False,\n",
    "    },\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d1ea0a1b-78f9-4be3-9479-228d6e679268",
   "metadata": {
    "height": 233
   },
   "outputs": [],
   "source": [
    "groupchat = autogen.GroupChat(\n",
    "    agents=[user_proxy, engineer, writer, executor, planner],\n",
    "    messages=[],\n",
    "    max_round=10,\n",
    "    allowed_or_disallowed_speaker_transitions={\n",
    "        user_proxy: [engineer, writer, executor, planner],\n",
    "        engineer: [user_proxy, executor],\n",
    "        writer: [user_proxy, planner],\n",
    "        executor: [user_proxy, engineer, planner],\n",
    "        planner: [user_proxy, engineer, writer],\n",
    "    },\n",
    "    speaker_transitions_type=\"allowed\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a62255bb-644f-4af6-a640-08297e55de45",
   "metadata": {
    "height": 148
   },
   "outputs": [],
   "source": [
    "manager = autogen.GroupChatManager(\n",
    "    groupchat=groupchat, llm_config=llm_config\n",
    ")\n",
    "\n",
    "groupchat_result = user_proxy.initiate_chat(\n",
    "    manager,\n",
    "    message=task,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e738fd8b",
   "metadata": {},
   "source": [
    "**Note**: You might experience slightly different interactions between the agents. The engineer agent may write incorrect code, which the executor agent will report and send back for correction. This process could go through multiple rounds."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
